การเปลี่ยนจากโปรแกรมมิ่งแบบซีเรียลของหน่วยประมวลผลหลัก (CPU) ไปเป็นโปรแกรมมิ่งบนหน่วยประมวลผลกราฟิก (GPU) จำเป็นต้องเปลี่ยนแนวคิดหลัก: จากการวนซ้ำทีละองค์ประกอบ ไปยัง การดำเนินงานแบบแบ่งเป็นบล็อก เราไม่ได้มองข้อมูลเป็นลำดับของตัวแปรสเกลาร์อีกต่อไป แต่เป็นชุดของ "บล็อก" ที่ถูกวางแผนให้ใช้ทรัพยากรความกว้างของแบนด์วิดธ์ฮาร์ดแวร์อย่างเต็มที่
1. จำกัดด้วยหน่วยความจำ หรือ จำกัดด้วยการคำนวณ
จุดที่ทำให้การทำงานช้าลงของเคอร์เนล (kernel) ขึ้นอยู่กับอัตราส่วนระหว่างจำนวนการดำเนินการทางคณิตศาสตร์ กับ การเข้าถึงหน่วยความจำ การบวกเวกเตอร์มักจะถูกจำกัดด้วยหน่วยความจำ เพราะมันดำเนินการเพียงแค่การบวกครั้งเดียวต่อการเข้าถึงหน่วยความจำ 3 ครั้ง (โหลด 2 ครั้ง และบันทึก 1 ครั้ง) ฮาร์ดแวร์ใช้เวลาในการรอข้อมูลจากหน่วยความจำ (DRAM) มากกว่าการคำนวณ
2. บทบาทของขนาดบล็อก (BLOCK_SIZE)
ขนาดบล็อก (BLOCK_SIZE) กำหนดระดับความละเอียดของการประมวลผลแบบขนาน หากขนาดเล็กเกินไป จะทำให้เราไม่สามารถใช้ประโยชน์จากช่องทางการประมวลผลที่กว้างของ GPU ได้อย่างเต็มที่ ขนาดที่เหมาะสมจะช่วยให้มีงานที่กำลังดำเนินการอยู่ (work in flight) เพียงพอ เพื่อใช้แบนด์วิดธ์หน่วยความจำให้เต็มประสิทธิภาพ
3. การซ่อนความล่าช้าผ่านการใช้งาน (Occupancy)
การใช้งาน (Occupancy) หมายถึง จำนวนบล็อกที่ทำงานอยู่พร้อมกันบนหน่วยประมวลผลกราฟิก (GPU) แม้จะไม่ใช่เป้าหมายสุดท้าย แต่มันช่วยให้ตัวจัดสรรงาน (scheduler) สามารถสลับไปยังบล็อกใหม่เพื่อทำการคำนวณ ขณะที่บล็อกอื่นๆ กำลังรอการดึงข้อมูลจากหน่วยความจำที่มีความล่าช้าสูง (VRAM)
4. การใช้ทรัพยากรฮาร์ดแวร์อย่างมีประสิทธิภาพ
เพื่อเพิ่มประสิทธิภาพสูงสุด เราต้องปรับขนาดบล็อกของเราให้สอดคล้องกับกฎการรวมข้อมูลหน่วยความจำ (memory coalescing rules) ของสถาปัตยกรรม GPU ขนาดบล็อก (BLOCK_SIZE) เพื่อให้แน่ใจว่าเส้นทางการเข้าถึงหน่วยความจำของเธรดที่ต่อเนื่องกัน ไปยังตำแหน่งหน่วยความจำที่ต่อเนื่องกัน